#ifndef BLOB_NET_H
#define BLOB_NET_H

/* Ethernet */
#define ETH_ALEN	6
#define ETHPROTO_IP	0x0800
#define ETHPROTO_ARP	0x0806
#define ETHPROTO_RARP	0x8035

/* IP */
#define IPPROTO_ICMP	1
#define IPPROTO_UDP	17

#define IP_DF		0x4000
#define IP_MF		0x2000
#define IP_OFFMASK	0x1fff

#define IPVERSION 	4
#define MAXTTL		8

/* ARP */
#define ARPHDR_ETHER	1

#define ARP_REQUEST	1
#define ARP_REPLY	2
#define ARP_REVREQUEST	3
#define ARP_REVREPLY	4

/* ICMP */
#define ICMP_MINLEN	8

#define ICMP_ECHOREPLY	0
#define ICMP_UNREACH	3
#define ICMP_ECHO	8

struct etherhdr 
{
	unsigned char 	eh_dhost[ETH_ALEN];
	unsigned char 	eh_shost[ETH_ALEN];
	unsigned short 	eh_proto;
}__attribute__ ((__packed__));

struct in_addr
{
	unsigned char addr[4];
}__attribute__ ((__packed__));

struct iphdr
{
	unsigned char 	ip_hl : 4,
		      	ip_v  : 4;
	unsigned char 	ip_tos;
	short 		ip_len;
	unsigned short	ip_id;
	short		ip_off;
	unsigned char	ip_ttl;
	unsigned char 	ip_p;
	unsigned short	ip_sum;
	struct in_addr	ip_src, ip_dst;
}__attribute__ ((__packed__));

struct udphdr
{
	unsigned short 	uh_sport;
	unsigned short 	uh_dport;
	short		uh_len;
	unsigned short	uh_sum;
}__attribute__ ((__packed__));

struct udp_port {
	unsigned short port;
	int (*handler)();
};

struct icmphdr
{
	unsigned char	type; 
	unsigned char	code;
	unsigned short	cksum;
	union {
		struct in_addr	gwaddr;
		struct {
			unsigned short	id;
			unsigned short	seq;
		}idseq;
		struct {
			unsigned short 	__unused;
			unsigned short	mtu;
		}mtu;
	} body;
}__attribute__ ((__packed__));

struct arphdr
{
	unsigned short	ar_hrd;
	unsigned short 	ar_pro;
	unsigned char	ar_hln;
	unsigned char	ar_pln;
	unsigned short	ar_op;	
}__attribute__ ((__packed__));

struct ether_arp 
{
	struct	arphdr	ea_hdr;
	unsigned char	arp_sha[6];
	unsigned char	arp_spa[4];
	unsigned char	arp_tha[6];
	unsigned char 	arp_tpa[4];
}__attribute__ ((__packed__));

#define BUFSZ	2048

struct mybuf{
	int len;
	unsigned char buf[BUFSZ];

	struct iphdr *ip;
	struct arphdr *arp;
	struct udphdr *udp;
	struct etherhdr *ether;
	struct ether_arp *etharp;
};

#define ntohs(x) ( ( ( (x) & 0xff ) << 8 ) |  ( ((x)>> 8) & 0xff) )
#define htons(x) ( ( ( (x) & 0xff ) << 8 ) |  ( ((x)>> 8) & 0xff) )


struct mybuf *bget(int io);
void net_rx();
void net_reset();

void net_init(void);
void net_test(void);
int cmd_tftp(u8* filename, u8* dest_address);
int cmd_ifconfig(u8* conf, u8* address);

#endif
